package org.lites.dcimmodifier;

import java.io.File;
import java.text.Collator;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Locale;

/**
 * 文件遍历器
 */
public class FileTraverser {
    /**
     * 是否包含指定扩展名
     * @param ext 待判断的扩展名
     * @param exts 指定的扩展名组
     * @return 是否包含指定扩展名
     */
    public static Boolean containExt(String ext, String[] exts){
        for (String ext_:exts) {
            if(ext.contains(ext_)){
                return true;
            }
        }
        return false;
    }
    /**
     * 获取指定文件夹内所有包含exts扩展名的File对象集合
     * @param dir 指定文件夹
     * @param exts 指定扩展名组
     * @return 包含exts扩展名的File对象集合
     */
    public static List<File> getFileList(File dir,String[] exts) {
        final File[] files = dir.listFiles();
        final ArrayList<File> result = new ArrayList<>();
        if(files!=null){
            for (File file : files) {
                if (file.isFile() && containExt(file.getName(), exts)) {
                    result.add(file);
                } else if (file.isDirectory()) {
                    final List<File> qmcFile = getFileList(file, exts);
                    result.addAll(qmcFile);
                }
            }
        }
        if (result.size() > 0) {
            // 使用 Collator 进行中文拼音排序
            Collator collator = Collator.getInstance(Locale.CHINA);

            // 使用自定义的比较器：先按文件名不区分大小写排序，再按拼音排序
            result.sort(Comparator
                    .comparing(File::getName, String.CASE_INSENSITIVE_ORDER) // 按文件名排序，不区分大小写
                    .thenComparing(collator) // 按拼音排序
            );
        }
        return result;
    }
    /**
     * 获取指定文件夹内depth深度层次内所有包含exts扩展名的File对象集合
     * @param dir 指定文件夹
     * @param exts 指定扩展名组
     * @param depth 指定深度
     * @return 包含exts扩展名的File对象集合
     */
    public static List<File> getFileList(File dir,String[] exts,int depth) {
        final File[] files = dir.listFiles();
        depth=depth-1;
        final List<File> result = new ArrayList<>();
        if(files!=null){
            if (depth >= 0) {
                for (File file : files) {
                    if (file.isFile() && containExt(file.getName(), exts)) {
                        result.add(file);
                    } else if (file.isDirectory()) {
                        final List<File> qmcFile = getFileList(file, exts, depth);
                        result.addAll(qmcFile);
                    }
                }
            }
        }

        if (result.size() > 0) {
            // 使用 Collator 进行中文拼音排序
            Collator collator = Collator.getInstance(Locale.CHINA);

            // 使用自定义的比较器：先按文件名不区分大小写排序，再按拼音排序
            result.sort(Comparator
                    .comparing(File::getName, String.CASE_INSENSITIVE_ORDER) // 按文件名排序，不区分大小写
                    .thenComparing(collator) // 按拼音排序
            );
        }
        return result;
    }
    /**
     * 获取指定文件夹内所有包含exts扩展名的文件路径集合
     * @param dir 指定文件夹
     * @param exts 指定扩展名组
     * @return 包含exts扩展名的文件路径集合
     */
    public static List<String> getFileStringList(File dir,String[] exts) {
        final File[] files = dir.listFiles();
        final ArrayList<String> result = new ArrayList<>();
        if(files!=null){
            for (File file : files) {
                if (file.isFile() && containExt(file.getName(), exts)) {
                    result.add(file.getPath());
                } else if (file.isDirectory()) {
                    final List<String> qmcFile = getFileStringList(file, exts);
                    result.addAll(qmcFile);
                }
            }
        }
        if (result.size() > 0) {
            // 使用 Collator 进行中文拼音排序
            Collator collator = Collator.getInstance(Locale.CHINA);

            // 使用自定义的比较器：先按文件名不区分大小写排序，再按拼音排序
            result.sort(Comparator
                    .comparing(Object::toString, String.CASE_INSENSITIVE_ORDER) // 按文件名排序，不区分大小写
                    .thenComparing(collator) // 按拼音排序
            );
        }

        return result;
    }
    /**
     * 获取指定文件夹内depth深度层次内所有包含exts扩展名的文件路径集合
     * @param dir 指定文件夹
     * @param exts 指定扩展名组
     * @param depth 指定深度
     * @return 包含exts扩展名的文件路径集合
     */
    public static List<String> getFileStringList(File dir,String[] exts,int depth) {
        final File[] files = dir.listFiles();
        depth=depth-1;
        final List<String> result = new ArrayList<>();
        if(files!=null){
            if (depth >= 0) {
                for (File file : files) {
                    if (file.isFile() && containExt(file.getName(), exts)) {
                        result.add(file.getPath());
                    } else if (file.isDirectory()) {
                        final List<String> qmcFile = getFileStringList(file, exts, depth);
                        result.addAll(qmcFile);
                    }
                }
            }
        }
        if (result.size() > 0) {
            // 使用 Collator 进行中文拼音排序
            Collator collator = Collator.getInstance(Locale.CHINA);

            // 使用自定义的比较器：先按文件名不区分大小写排序，再按拼音排序
            result.sort(Comparator
                    .comparing(Object::toString, String.CASE_INSENSITIVE_ORDER) // 按文件名排序，不区分大小写
                    .thenComparing(collator) // 按拼音排序
            );
        }

        return result;
    }
    /**
     * 获取指定文件夹内所有文件夹的File对象集合
     * @param dir 指定文件夹
     * @return 所有文件夹的File对象集合
     */
    public static List<File> getDirList(File dir) {
        final File[] files = dir.listFiles();
        final ArrayList<File> result = new ArrayList<>();
        if (files != null) {
            for (File file : files) {
                if (file.isDirectory()) {
                    result.add(file);
                    final List<File> qmcFile = getDirList(file);
                    result.addAll(qmcFile);
                }
            }
        }
        if (result.size() > 0) {
            // 使用 Collator 进行中文拼音排序
            Collator collator = Collator.getInstance(Locale.CHINA);

            // 使用自定义的比较器：先按文件名不区分大小写排序，再按拼音排序
            result.sort(Comparator
                    .comparing(File::getName, String.CASE_INSENSITIVE_ORDER) // 按文件名排序，不区分大小写
                    .thenComparing(collator) // 按拼音排序
            );
        }
        return result;
    }
    /**
     * 获取指定文件夹内depth深度层次内所有文件夹的File对象集合
     * @param dir 指定文件夹
     * @param depth 指定深度
     * @return 所有文件夹的File对象集合
     */
    public static List<File> getDirList(File dir,int depth){
        final File[] files = dir.listFiles();
        depth=depth-1;
        final List<File> result = new ArrayList<>();
        if(files!=null){
            if (depth >= 0) {
                for (File file : files) {
                    if (file.isDirectory()) {
                        result.add(file);
                        final List<File> qmcFile = getDirList(file, depth);
                        result.addAll(qmcFile);
                    }
                }
            }
        }
        if (result.size() > 0) {
            // 使用 Collator 进行中文拼音排序
            Collator collator = Collator.getInstance(Locale.CHINA);

            // 使用自定义的比较器：先按文件名不区分大小写排序，再按拼音排序
            result.sort(Comparator
                    .comparing(File::getName, String.CASE_INSENSITIVE_ORDER) // 按文件名排序，不区分大小写
                    .thenComparing(collator) // 按拼音排序
            );
        }
        return result;
    }
    /**
     * 获取指定文件夹内所有文件夹的路径集合
     * @param dir 指定文件夹
     * @return 所有文件夹的路径集合
     */
    public static List<String> getDirStringList(File dir){
        final File[] files = dir.listFiles();
        final List<String> result = new ArrayList<>();
        if (files != null) {
            for (File file : files) {
                if (file.isDirectory()) {
                    result.add(file.getPath());
                    final List<String> qmcFile = getDirStringList(file);
                    result.addAll(qmcFile);
                }
            }
        }
        if (result.size() > 0) {

            // 使用 Collator 进行中文拼音排序
            Collator collator = Collator.getInstance(Locale.CHINA);

            // 使用自定义的比较器：先按文件名不区分大小写排序，再按拼音排序
            result.sort(Comparator
                    .comparing(Object::toString, String.CASE_INSENSITIVE_ORDER) // 按文件名排序，不区分大小写
                    .thenComparing(collator) // 按拼音排序
            );
        }
        return result;
    }
    /**
     * 获取指定文件夹内depth深度层次内所有文件夹的路径集合
     * @param dir 指定文件夹
     * @param depth 指定深度
     * @return 所有文件夹的路径集合
     */
    public static List<String> getDirStringList(File dir,int depth){
        final File[] files = dir.listFiles();
        depth=depth-1;
        final List<String> result = new ArrayList<>();
        if(files!=null){
            if (depth >= 0) {
                for (File file : files) {
                    if (file.isDirectory()) {
                        result.add(file.getPath());
                        final List<String> qmcFile = getDirStringList(file, depth);
                        result.addAll(qmcFile);
                    }
                }
            }
        }
        if (result.size() > 0) {
            // 使用 Collator 进行中文拼音排序
            Collator collator = Collator.getInstance(Locale.CHINA);

            // 使用自定义的比较器：先按文件名不区分大小写排序，再按拼音排序
            result.sort(Comparator
                    .comparing(Object::toString, String.CASE_INSENSITIVE_ORDER) // 按文件名排序，不区分大小写
                    .thenComparing(collator) // 按拼音排序
            );

        }
        return result;
    }

    /**
     * 获取指定文件夹内指定文件名的完整文件路径
     * @param dir 指定文件夹
     * @param fileName 指定文件名
     * @return 指定文件名的完整文件路径
     */
    public static String getFileName(File dir,String fileName){
        List<File>fileList=getFileList(dir,new String[]{"."});
        fileName=fileName.substring(0, fileName.lastIndexOf("."));
        for (File file:fileList) {
            String dirfilename=file.getName();
            if(dirfilename.contains(fileName)){
                return dirfilename;
            }
        }
        return "";
    }
    /**
     * 判断指定文件夹内是否包含指定文件名的文件
     * @param dir 指定文件夹
     * @param fileName 指定文件名
     * @return 是否包含指定文件名的文件
     */
    public static Boolean containFile(File dir, String fileName){
        return !getFileName(dir, fileName).equals("");
    }
}
